#include "mylistobject.h"

#include <math.h>
#include <qdebug.h>



static GLfloat boxcol[5][3]=
{
    {1,0,0},
    {1,0.5,0},
    {1,0.5,1},
    {0,1,0},
    {0,0,1}
};
static GLfloat topcol[5][3]=
{
    {1,0,1},
    {1,0.5,1},
    {0,0,1},
    {0,1,0},
    {0,1,1}
};
mylistobject::mylistobject():
    QGLWidget()
{
    mRotate_z=mRotate_y=mRotate_x=0;

}

mylistobject::~mylistobject()
{

}

void mylistobject::initializeGL()
{


    glShadeModel(GL_SMOOTH);

    glClearColor(0,0,0,1);
    glClearDepth(1.0);

    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LEQUAL);

    glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST);

    glPolygonMode(GL_FRONT,GL_FILL);
    glPolygonMode(GL_BACK,GL_FILL);


    LoadGLTextures();
    glEnable(GL_TEXTURE_2D);

    //颜色材料
    glEnable(GL_COLOR_MATERIAL);
    BuildList();
}

void mylistobject::resizeGL(int w, int h)
{
    glViewport(0,0,w,h);

    glMatrixMode(GL_PROJECTION);
    glFrustum(-2,2,-(float)h/w*2,(float)h/w*2,1,20);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
}

void mylistobject::paintGL()
{
    int x,y;
    float float_x,float_y,float_xb,float_yb;
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

    //glBindTexture(GL_TEXTURE_2D,mTexture[0]);

    for(int y=1;y<6;y++)
    {
        for(int x=0;x<y;x++)
        {
            glLoadIdentity();
            glTranslatef(1.4+(float(x)*2.8)-(float(y)*1.4),((6.0-float(y))*2.4)-7.0,-10.0f);

            glRotatef(45.0f-(2.0f*y)+x,1.0f,0.0f,0.0f);
            glRotatef(45.0f+y,0.0f,1.0f,0.0f);

            glColor3fv(boxcol[y-1]);
            //不需要写出画多边形的代码，只需要用glCallList(box)命令调用显示列表
            glCallList(mBox);


            glColor3fv(topcol[y-1]);
            glCallList(mTop);
        }
    }
    renderText(0,0,-15,"Hello");
}
int mylistobject::LoadGLTextures()
{
    QImage image("G:\\Project\\OpenGL\\lena.jpg");
    if(image.isNull())
    {
        qDebug()<<"Image Is Null";
        return 1;
    }
    else
        qDebug()<<"w:"<<image.width();
    QImage Tex=QGLWidget::convertToGLFormat(image);

    glGenTextures(3,mTexture);

    glBindTexture(GL_TEXTURE_2D,mTexture[0]);
    glTexImage2D(GL_TEXTURE_2D,0,3,image.width(),image.height(),0,GL_RGBA,GL_UNSIGNED_BYTE,Tex.bits());
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);

    glBindTexture(GL_TEXTURE_2D,mTexture[1]);
    glTexImage2D(GL_TEXTURE_2D,0,3,image.width(),image.height(),0,GL_RGBA,GL_UNSIGNED_BYTE,Tex.bits());
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);

    glBindTexture(GL_TEXTURE_2D,mTexture[2]);
    glTexImage2D(GL_TEXTURE_2D,0,3,image.width(),image.height(),0,GL_RGBA,GL_UNSIGNED_BYTE,Tex.bits());
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NICEST);
}
void mylistobject::BuildList()
{
    //建立两个列表的空间，返回第一个显示列表的指针
    mBox=glGenLists(2);
    //告诉OpenGL预先在内存中构造这个列表
    //glNewList/glEndList之间的Object都会放在list中，且在box指向的内存空间中
    glNewList(mBox,GL_COMPILE);
        glBegin(GL_QUADS);							// 开始绘制四边形

                // 底面

                glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, -1.0f, -1.0f);

                glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, -1.0f, -1.0f);

                glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f,  1.0f);

                glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f,  1.0f);

                // 前面

                glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f,  1.0f);

                glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f,  1.0f);

                glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f,  1.0f,  1.0f);

                glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f,  1.0f,  1.0f);

                // 后面

                glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);

                glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f,  1.0f, -1.0f);

                glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f,  1.0f, -1.0f);

                glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);

                // 右面

                glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);

                glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f,  1.0f, -1.0f);

                glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f,  1.0f,  1.0f);

                glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f,  1.0f);

                // 左面

                glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);

                glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f,  1.0f);

                glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f,  1.0f,  1.0f);

                glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f,  1.0f, -1.0f);

            glEnd();								// 四边形绘制结束

    glEndList();

    //构造top指向的list内存空间
    mTop=mBox+1;
    glNewList(mTop,GL_COMPILE);
        glBegin(GL_QUADS);							// 开始绘制四边形

                // 上面

                glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f,  1.0f, -1.0f);

                glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f,  1.0f,  1.0f);

                glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f,  1.0f,  1.0f);

                glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f,  1.0f, -1.0f);

            glEnd();
    glEndList();

}

void mylistobject::keyPressEvent(QKeyEvent* e)
{
    switch(e->key())
    {
    case Qt::Key_Left:
        mRotate_z-=10;
        break;
    case Qt::Key_Right:
        mRotate_z+=10;
        break;
    case Qt::Key_Up:
        mRotate_x-=10;
        break;
    case Qt::Key_Down:
        mRotate_x+=10;
        break;
    case Qt::Key_Plus:
        mMove_z+=1;
        break;
    case Qt::Key_Minus:
        mMove_z-=1;
        break;
    case Qt::Key_L:
    {
        GLboolean light;
        glGetBooleanv(GL_LIGHTING,&light);
        light=!light;
        if(light)
            glEnable(GL_LIGHTING);
        else
            glDisable(GL_LIGHTING);
    }
    case Qt::Key_B:
    {
        GLboolean blend;
        glGetBooleanv(GL_BLEND,&blend);
        blend=!blend;
        if(blend)
        {
            glEnable(GL_BLEND);
            glDisable(GL_DEPTH_TEST);
        }
        else
        {
            glDisable(GL_BLEND);
            glEnable(GL_DEPTH_TEST);
        }
    }
    }
    updateGL();
}

